package com.tangyanbo.filemanager.common.compress;

import java.io.BufferedInputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;

import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;
import org.apache.tools.zip.ZipOutputStream;

public class Compress {

	private static final int BUFFER = 1024 * 1024;

	public static void main(String args[]) throws Exception {
		File inputFile = new File("C:\\Users\\tangyanb\\Downloads\\3677");
		File outputFile = new File("C:\\Users\\tangyanb\\Downloads\\test.zip");
		zip(inputFile, outputFile);
		// String zipFile = "C:\\Users\\tangyanb\\Downloads\\test.zip";
		// String dest = "C:\\Users\\tangyanb\\Downloads\\";
		// unZip(zipFile,dest);
	}

	public static boolean zip(File inputFile, File outputFile){
		ZipOutputStream zipOut = null;
		try{
			zipOut = new ZipOutputStream(new FileOutputStream(
					outputFile));
			zip(zipOut,
					inputFile,
					outputFile.getName().substring(0,
							outputFile.getName().indexOf(".")));
			return true;
		}catch(Exception e){
			e.printStackTrace();
			return false;
		}finally{
			close(zipOut);
		}		
	}

	private static void zip(ZipOutputStream zipOut, File inputFile, String base)
			throws Exception {
		if (inputFile.isDirectory()) {
			File[] file = inputFile.listFiles();
			zipOut.putNextEntry(new ZipEntry(base + "/"));
			base = base.length() == 0 ? "" : base + "/";
			for (int i = 0; i < file.length; i++) {
				zip(zipOut, file[i], base + file[i].getName());
			}
		} else {
			zipOut.putNextEntry(new ZipEntry(base));
			FileInputStream in = null;
			BufferedInputStream bis = null;
			int len;
			byte[] buf = new byte[BUFFER];
			try {
				in = new FileInputStream(inputFile);
				bis = new BufferedInputStream(in);
				while ((len = bis.read(buf)) != -1) {
					zipOut.write(buf, 0, len);
				}
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				close(in);
				close(bis);
			}
		}
	}

	@SuppressWarnings("unchecked")
	public static boolean unZip(File zipfile, String destDir) {
		destDir = destDir.endsWith("//") ? destDir : destDir + "//";
		byte buffer[] = new byte[BUFFER];
		int length;
		ZipFile zipFile;
		try {
			zipFile = new ZipFile(zipfile);
			Enumeration<ZipEntry> enumeration = zipFile.getEntries();
			ZipEntry zipEntry = null;
			while (enumeration.hasMoreElements()) {
				zipEntry = (ZipEntry) enumeration.nextElement();
				File loadFile = new File(destDir + zipEntry.getName());
				if (zipEntry.isDirectory()) {
					loadFile.mkdirs();
				} else {
					if (!loadFile.getParentFile().exists()) {
						loadFile.getParentFile().mkdirs();
					}
					OutputStream outputStream = null;
					InputStream inputStream = null;
					try {
						outputStream = new FileOutputStream(loadFile);
						inputStream = zipFile.getInputStream(zipEntry);
						while ((length = inputStream.read(buffer)) > 0) {
							outputStream.write(buffer, 0, length);
						}
					} catch (Exception e) {
						return false;
					} finally {
						close(inputStream);
						close(outputStream);
					}
				}
			}
			return true;
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}
	}

	private static void close(Closeable stream) {
		if (stream != null) {
			try {
				stream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}
